package org.outlook.crawler.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
/**
 * process HTML stuff like convert Numeric Reference To Normal character
 * @author bwu@xtremeprog.com
 *
 */
public class HtmlCharacterReferenceUtil {
	
	public static String processNumericReferenceToNormal(String content) {
		String regex = "(&#.+?;)";
		Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        List<String> result = new ArrayList<String>();
        String temp = null;
        int i = 0;
        while(matcher.find()) {
        	temp = matcher.group();
        	result.add(temp);
        	content = content.replace(temp, "${"+ (i++) +"}");
        }
        i = 0;
        if(null != result && !result.isEmpty()) {
        	for(String s : result) {
        		content = content.replace("${"+ (i++) + "}", excapseUnicode(getUnicodeString(s)));
        	}
        }
		return content;
	}
	
	public static String getUnicodeString(String htmlNumericReference) {
		if(null == htmlNumericReference) return null;
		try {
			String unicode = htmlNumericReference.replace("&#", "");
			if(null == unicode) return null;
			int unicodeBinary = Integer.parseInt(unicode.substring(0, unicode.indexOf(";")));
			String hexString = Integer.toHexString(unicodeBinary);
			return "\\u"+hexString;
		} catch(Exception e) {
			return htmlNumericReference;
		}
	}
	
	public static String excapseUnicode(String unicode) {
		if(null == unicode) return null;
		String str = unicode.replace("\\u","");
		String s = ""+(char)Integer.parseInt(str,16);  
		return s;
	}
	
	final static Pattern CHARSET_PATTERN = Pattern.compile("<meta .+ content=\".+?; charset=(.+?)\" />");
	
	public static String getHtmlCharset(String htmlSource) {
		if(StringUtils.isNotBlank(htmlSource)) {
			int headerStart = htmlSource.contains("<head>")?htmlSource.indexOf("<head>"):htmlSource.contains("<HEAD>")?htmlSource.indexOf("<HEAD>"):-1;
			int headerEnd = (htmlSource.contains("</head>")?htmlSource.indexOf("</head>"):htmlSource.contains("</HEAD>")?htmlSource.indexOf("</HEAD>"):-1)+7;
			if(headerStart>-1 && headerEnd>-1) {
				Matcher matcher = CHARSET_PATTERN.matcher(htmlSource.substring(headerStart, headerEnd).toLowerCase());
				if(matcher.find())
					return matcher.group(1);
			}
		}
		return null;
	}

}
